#include <google/protobuf/util/json_util.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>

#include <iostream>
#include <unistd.h>
#include <cstring>
#include <arpa/inet.h>

#include "test.pb.h"


std::string to_string(const Person& person);

int run()
{
    // 创建客户端套接字
    int clientSocket = socket(AF_INET, SOCK_STREAM, 0);
    if (clientSocket == -1) {
        std::cerr << "Error creating socket" << std::endl;
        return -1;
    }

    // 设置服务器地址和端口
    sockaddr_in serverAddr;
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_addr.s_addr = inet_addr("127.0.0.1"); // 服务器的IP地址
    serverAddr.sin_port = htons(50051);

    // 连接到服务器
    if (connect(clientSocket, (struct sockaddr*)&serverAddr, sizeof(serverAddr)) == -1) {
        std::cerr << "Error connecting to server" << std::endl;
        close(clientSocket);
        return -1;
    }

    google::protobuf::io::FileOutputStream clientFileOutStream(clientSocket);
    google::protobuf::io::CodedOutputStream clientOutStream(&clientFileOutStream);
    google::protobuf::io::FileInputStream clientInStream(clientSocket);

    for (int i = 1; i < 10000; i++)
    {
        Person person;
        person.set_id(i);

        clientOutStream.WriteVarint32(person.ByteSizeLong());

        // 向服务器发送数据
        person.SerializePartialToCodedStream(&clientOutStream);

        // 接收服务器的响应
        if (person.ParseFromZeroCopyStream(&clientInStream)) {
            std::cout << "Server response: " << to_string(person) << std::endl;
        }
    }

    // 关闭客户端套接字
    close(clientSocket);

    return 0;
}

std::string to_string(const Person& person)
{
    std::string json_string;
    google::protobuf::util::JsonPrintOptions options;
    options.add_whitespace = true;  // 可选：添加空格以便更好地可读性
    auto res = google::protobuf::util::MessageToJsonString(person, &json_string, options);
    // std::cout << "res status: " << res.ok() << "\n";
    return json_string;
}

int main(int argc, char* argv[])
{
    GOOGLE_PROTOBUF_VERIFY_VERSION;

    run();
    
    return 0;
}